﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Cherry.Agile.Configuration;

namespace Cherry.Agile.Core
{
    /// <summary>
    /// IOC 容器
    /// </summary>
    public static class Container
    {
        const string CONTAINER_NAME = "agile";

        static Lazy<IUnityContainer> _current;
        static UnityConfigurationSection _section;

        public static void Setup(string file)
        {
            var config = ConfigManager.Create(file);
            Setup(config);
        }

        public static void Setup(ConfigManager config)
        {
            _section = config.GetSection("unity") as UnityConfigurationSection;
        }

        static Container()
        {
            _current = new Lazy<IUnityContainer>(Create);
            
        }

        /// <summary>
        /// 创建一个子容器
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer CreateChildContainer()
        {
            return Current.CreateChildContainer();
        }

        /// <summary>
        /// 创建一个新的容器
        /// </summary>
        /// <returns></returns>
        public static IUnityContainer CreateContainer()
        {
            return new UnityContainer();
        }

        static IUnityContainer Create()
        {

            var current = new UnityContainer();
            try
            {
                if (_section != null)
                    current.LoadConfiguration(_section, CONTAINER_NAME);
                else
                    current.LoadConfiguration(CONTAINER_NAME);
            }
            catch (System.Configuration.ConfigurationErrorsException ce)
            {
                throw new System.Configuration.ConfigurationErrorsException("Unity配置错误，请确认配置文件中存在Unity配置节", ce);
            }
            catch (ArgumentNullException)
            {

            }
            catch
            {
                throw;
            }
            _section = null;
            return current;
        }

        /// <summary>
        /// Unity容器<see cref="Microsoft.Practices.Unity.IUnityContainer"/>
        /// </summary>
        public static IUnityContainer Current
        {
            get
            {
                return _current.Value;
            }

        }
    }
}
